#ifndef __ETL_H__
#define __ETL_H__

//#define WINVER		0x0500
//#define _WIN32_WINNT	0x0500
//#define _WIN32_IE		0x0500
#ifdef _WIN32
#define WINDOWS_SYSTEM		1
#define LINUX_SYSTEM		0
#else
#define WINDOWS_SYSTEM		0
#define LINUX_SYSTEM		1
#endif

#define PRIVATE_CLASS class
#define PRIVATE_STRUCT struct

////////////////////////////// chINRANGE Macro ////////////////////////////////
// This macro returns TRUE if a number is between two others
#define chINRANGE(low, Num, High)	(((low) <= (Num)) && ((Num) <= (High)))
#define chMAX(a, b)					((a)>(b)?(a):(b))
#define chMIN(a, b)					((a)<(b)?(a):(b))
#define chMID(a, b, c)				((a)>(b)?((b)>(c)?(b):chMIN(a,c)):((a)>(c)?(a):chMIN(b,c)))

#define chCHECK_BITS(u, flag)		(((u) & (flag)) == (flag))
#define chSET_BITS(u, mask, bSet)	((bSet) ? ((u) |= (mask)) : ((u) &= ~(mask)))

#define _B4(b0,b1,b2,b3)			(((b0)<<0)|((b1)<<1)|((b2)<<2)|((b3)<<3))
#define _B16(b0,b1,b2,b3)			(((b0)<<0)|((b1)<<4)|((b2)<<8)|((b3)<<12))

#define chMAKEBYTE(lb, hb)			((BYTE)(((BYTE)(lb)) | (((BYTE)(hb))) << 4))
#define chMAKEWORD(lb, hb)			((WORD)(((BYTE)(lb)) | ((WORD)((BYTE)(hb))) << 8))
#define chMAKELONG(lw, hw)			((LONG)(((WORD)(lw)) | ((DWORD)((WORD)(hw))) << 16))
#define chLOWORD(l)					((WORD)(l))
#define chHIWORD(l)					((WORD)(((DWORD)(l) >> 16) & 0xFFFF))
#define chLOBYTE(w)					((BYTE)(w))
#define chHIBYTE(w)					((BYTE)(((WORD)(w) >> 8) & 0xFF))

#define chCEIL(n, row)				(((n)-1) - ((n)-1) % (row) + (row))
#define chFLOOR(n, row)				((n) - ((n) % (row)))

//////////////////////////////// chDIMOF Macro ////////////////////////////////
// This macro evaluates to the number of elements in an array. 
#define chLENOF(Array) (sizeof(Array) / sizeof(Array[0]))

#define chTEXT_SAME(s1, s2) (chStrcmp<TCHAR, true>(s1, s2) == 0)
#define chTEXT_LIKE(s1, s2) (chStrcmp<TCHAR, false>(s1, s2) == 0)
#define chTEXT_BEGIN(lpszText, lpszSub) (chIsBeginText<TCHAR, true>(lpszText, lpszSub))

#define chIS_EMPTY(str) ((str) == NULL || *(str) == '\0')
////////////////// DebugBreak Improvement for x86 platforms ///////////////////
#ifdef _X86_
#define DebugBreak()    _asm { int 3 }
#endif

//////////////////////////// Assert/Verify Macros /////////////////////////////
// Put up a message box if an assertion fails in a debug build.
#ifdef _DEBUG
#define chASSERT(expr) \
        do { if (!(expr) && \
                (1 == _CrtDbgReport(_CRT_ASSERT, __FILE__, __LINE__, NULL, #expr))) \
             _CrtDbgBreak(); } while (0)

#else
#define chASSERT(expr)
#endif

// Assert in debug builds, but don't remove the code in retail builds.
#ifdef _DEBUG
#define chVERIFY(x) chASSERT(x)
#else
#define chVERIFY(x) (x)
#endif

#define VA_LIST(vFrom)	va_list argList; va_start(argList, vFrom)
#define VA_ARG(type) va_arg(argList, type)

#if LINUX_SYSTEM
#include <xInc/xDef.h>
#else 
#include "wInc/wDef.h"
#endif

#include "_chAlloc.h"		// some userful class no system relation
#include "_chArray.h"		// such as array, list, map, simple map
#include "_chString.h"
#include "_chList.h"
#include "_chMap.h"

#include "uMics.h"			// some userful API no system relation

#if LINUX_SYSTEM
#include <xInc/xSDK.h>
#else 
#include "wInc/wSDK.h"
#endif

#include "uBaseClass.h"

#endif //__ETL_H__